#include <iostream>
#include <string>
#include <vector>
#include <set>

#include <sw/redis++/redis++.h>

#include "util.hpp"

using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::set;

namespace redis = sw::redis;

void test_sadd_and_smembers(redis::Redis& redis){
    cout << "test sadd and smembers" << endl;
    redis.flushall();

    // 可以单个添加
    redis.sadd("key1", "111");
    // 一次性添加多个
    redis.sadd("key1", {"222", "333", "444"});
    // 使用容器
    vector<string> nums = {"555", "666", "777"};
    redis.sadd("key1", nums.begin(), nums.end());

    // 获取集合中的所有元素
    // back_inserter 和 push_back 捆绑
    // inserter 和 insert 捆绑
    set<string> res;
    auto it = std::inserter(res, res.end());
    redis.smembers("key1", it);
    printContainer(res);
}

void test_sismember_and_scard(redis::Redis& redis){
    cout << "test sismember and scard" << endl;
    redis.flushall();

    redis.sadd("key1", {"222", "333", "444"});

    auto res = redis.sismember("key1", "222");

    cout << "key1 的 222: " << res << endl;

    cout << "key1 元素个数: " << redis.scard("key1") << endl;
}

void test_spop(redis::Redis& redis){
    cout << "test spop" << endl;
    redis.flushall();
    redis.sadd("key1", {"222", "333", "444"});

    auto res = redis.spop("key1");
    if(res){
        cout << "key1 pop: " << res.value() << endl;
    }

    vector<redis::OptionalString> out;
    auto it = std::inserter(out, out.end());
    redis.spop("key1", 3, it);

    for(auto& e : out){
        if(e){
            cout << "key1 pop: " << e.value() << endl;
        }
        else{
            cout << "key1 pop: " << "null" << endl;
        }
    }

    // for(auto& e : out){
    //     cout << "key1 pop: " << e << endl;
    // }
}

void test_sinter_and_sinterstore(redis::Redis& redis){
    cout << "test sinter and sinterstore" << endl;
    redis.flushall();

    redis.sadd("key1", {"222", "333", "444"});
    redis.sadd("key2", {"333", "444", "555"});

    set<string> inter;
    auto it = std::inserter(inter, inter.end());
    redis.sinter({"key1", "key2"}, it);

    cout << "key1 和 key2 交集: " << endl;
    printContainer(inter);

    // sinterstore
    auto size = redis.sinterstore("key3", {"key1", "key2"});
    cout << "交集的个数: " << size << endl;
}


int main(){
    redis::Redis redis("tcp://666666@127.0.0.1:6379");

    // test_sadd_and_smembers(redis);
    // test_sismember_and_scard(redis);
    // test_spop(redis);
    test_sinter_and_sinterstore(redis);

    return 0;
}